﻿using AsmShaderConverter.AsmShader;
using AsmShaderConverter.HlslShader;
using System;

namespace AsmShaderConverter.AsmFunctions
{
    public class AsmFunctionTexldr : IConvertToHlsl
    {
        private readonly string originalLineOfCode;
        private Register destination;
        private Register coordinates;
        private Register sampler;

        public Register GetDestinationRegister()
        {
            return this.destination;
        }

        public AsmFunctionTexldr(string lineOfCode, bool halfPrecision)
        {
            this.originalLineOfCode = lineOfCode;
            lineOfCode = lineOfCode.Replace(",", ""); // Remove commas.
            lineOfCode = lineOfCode.Trim(); // Remove dead space.
            var values = lineOfCode.Split(' '); // split

            switch (values.Length)
            {
                case 4:
                    this.destination = new Register(values[1], halfPrecision, Swizzle.StandardXYZW);
                    this.coordinates = new Register(values[2], Swizzle.StandardXYZW);
                    this.sampler = new Register(values[3], Swizzle.StandardXYZW);
                    break;

                default:
                    throw new Exception("Function can´t be converted! " + lineOfCode);
            }
        }

        public string ToHLSL(AsmShaderFile asmShader)
        {
            string textureName = string.Empty;
            Sampler2Texture sampler;
            if (asmShader.GetSamplerToTextureName(this.sampler.OriginalRegisterName, out sampler))
                textureName = sampler.textureName;
            else
                textureName = "noneRegistered";

            switch (sampler.samplerState)
            {
                case EnumSamplerstate.Texture2D:
                    if (coordinates.swizzle.Length == 0)
                        coordinates.swizzle = new char[] { 'x', 'y' };

                    if (coordinates.swizzle.Length > 2)
                    {
                        coordinates.swizzle = new char[] { coordinates.swizzle[0], coordinates.swizzle[1] };
                    }
                    break;

                case EnumSamplerstate.TextureCube:
                    if (coordinates.swizzle.Length == 0)
                        coordinates.swizzle = new char[] { 'x', 'y', 'z' };

                    if (coordinates.swizzle.Length > 3)
                    {
                        coordinates.swizzle = new char[] { coordinates.swizzle[0], coordinates.swizzle[1], coordinates.swizzle[2] };
                    }

                    break;

                default: throw new Exception("unknown samplerstate!");
            }

            return String.Format("{0} = {1}.Sample({2}, {3});", this.destination.ToHLSL(asmShader), textureName, this.sampler.GetRegisterName(asmShader), this.coordinates.ToHLSL(asmShader));
        }

        public string ToHLSLWitchComment(AsmShaderFile asmShader)
        {
            return this.ToHLSL(asmShader) + "//" + this.originalLineOfCode;
        }
    }
}